#include "MainFrame.h"
#include "ImageCanvas.h"
#include "GaussianImageFilter.h"
#include "Image.h"
#include "ImageIO.h"
#include "wxMYPictureFrame.h"
#include <string>

#include <wx/stdpaths.h>
enum
{
    // menu items
	ID_LinearCPP = 100,
	ID_CUDA,
	ID_OPENCL,
	ID_OPENGL,
    ID_LoadImage = wxID_HIGHEST,
    ID_ShowSource
};

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
    EVT_CLOSE( MainFrame::OnClose)
    EVT_MENU(ID_LoadImage, MainFrame::OnLoadImage)
    EVT_MENU(ID_ShowSource, MainFrame::OnShowSource)
	EVT_MENU(ID_LinearCPP,MainFrame::OnGAUSS)
	EVT_MENU(ID_CUDA,MainFrame::OnGAUSS)
	EVT_MENU(ID_OPENCL,MainFrame::OnGAUSS)
	EVT_MENU(ID_OPENGL,MainFrame::OnGAUSS)
	//EVT_MENU()
END_EVENT_TABLE()

BEGIN_EVENT_TABLE(SourceFrame, wxFrame)
    EVT_MENU(wxID_EXIT,  SourceFrame::OnQuit)
END_EVENT_TABLE()


MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
   : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size,
             wxDEFAULT_FRAME_STYLE, wxT("html_test_app")),
			 m_canvas(0L),
			 m_pImg(0L)
{
	m_bmp = 0L;
	m_img_rev = 0L;
    // create a menu bar
    wxMenu *menuFile = new wxMenu;
	wxMenu *imageprocess = new wxMenu;
	imageprocess->Append(ID_LinearCPP,_("Run single Thread"));
	imageprocess->Enable(ID_LinearCPP,false);
	imageprocess->Append(ID_CUDA,_("Run multi Thread"));
	imageprocess->Enable(ID_CUDA,false);
	//imageprocess->Append(ID_OPENCL,_("Linear_OpenCL"));
	//imageprocess->Enable(ID_OPENCL,false);
	//imageprocess->Append(ID_OPENGL,_("OPENGL"));
	//imageprocess->Enable(ID_OPENGL,false);
   // wxMenu *menuNav = new wxMenu;

    menuFile->Append(ID_LoadImage, _("&Load image..."));
    menuFile->Append(ID_ShowSource, _("&Show source code"));
	menuFile->Enable(ID_ShowSource,false);
    menuFile->AppendSeparator();
    
    menuFile->Append(wxID_EXIT, _("&Close frame"));

    // now append the freshly created menu to the menu bar...
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append(menuFile, _("&File"));
	menuBar->Append(imageprocess,_("Gauss algorithim"));



    // ... and attach this menu bar to the frame
    SetMenuBar(menuBar);

	
	
   // m_canvas->SetScrollbars( 10, 10, 100, 240 );

//  //  SetIcon(wxIcon(sample_xpm));
//
//#if wxUSE_ACCEL
//    // Create convenient accelerators for Back and Forward navigation
//    wxAcceleratorEntry entries[2];
//    entries[0].Set(wxACCEL_ALT, WXK_LEFT, ID_Back);
//    entries[1].Set(wxACCEL_ALT, WXK_RIGHT, ID_Forward);
//
//    wxAcceleratorTable accel(WXSIZEOF(entries), entries);
//    SetAcceleratorTable(accel);
//#endif // wxUSE_ACCEL
//
//#if wxUSE_STATUSBAR
//    CreateStatusBar(2);
//#endif // wxUSE_STATUSBAR
//
//    m_Processor = new BoldProcessor;
//    m_Processor->Enable(false);
//    m_Html = new SourceWindow(this);
//    m_Html->SetRelatedFrame(this, _("HTML : %s"));
//#if wxUSE_STATUSBAR
//    m_Html->SetRelatedStatusBar(0);
//#endif // wxUSE_STATUSBAR
//    m_Html->ReadCustomization(wxConfig::Get());
//    m_Html->LoadFile(wxFileName(wxT("C:\\Documents and Settings\\19003854\\Desktop\\wxWidgets-HtmlDemo-Windows\\test.htm")));
//    m_Html->AddProcessor(m_Processor);
}




void MainFrame::OnClose(wxCloseEvent& event)
{
   // m_Html->WriteCustomization(wxConfig::Get());
   if(m_bmp) delete m_bmp;
   if(m_canvas)
	   delete m_canvas;
   if(m_pImg)
	   delete m_pImg;
   if(m_img_rev)
	   delete m_img_rev;
   wxFrame::OnCloseWindow(event);

    // true is to force the frame to close
   // Close(true);
}

void MainFrame::OnLoadImage(wxCommandEvent& WXUNUSED(event))
{
	//using namespace NOVA;

    wxString p = wxFileSelector(_("Load JPEG image"), wxEmptyString,
        wxEmptyString, wxEmptyString, wxT("jpeg files|*.jpg|dicom files|*.dcm|tiff files|*.tif|.bmp|*.bmp"));
	
	//Usage:
	// 1. new a ImageIO Carrier with specific name.
	//  jpeg_ijg/tiff_libtiff/dicom_gdcm
	// 2. set the image 
	// 3. set image file name
	// 4. invoke Read();

	// Example:
	if(m_img_rev)
		{delete m_img_rev;m_img_rev = 0L;}
	if (!p.empty())
	{
	 NOVA::Image *img = new Image();//creat the memory.	?????
	//if(img)
	//	delete img;
	wxString extent = p.substr(p.find_last_of('.'),p.size());
	NovaIO::ImageIO *carrier = 0L;
	if(extent == _(".dcm") | extent == _(".DCM"))
		carrier = new NovaIO::ImageIO("dicom_gdcm");
	else if(extent == _(".jpg")||extent == ".JPG")
		carrier = new NovaIO::ImageIO("jpeg_ijg");
	else if(extent == _(".tif"))
		 carrier = new NovaIO::ImageIO("tiff_libtiff");
	else if(extent == _(".bmp"))
		carrier = new NovaIO::ImageIO("bmp_GDI");
	
	if(carrier)
	{
	carrier->SetImageName(p.c_str());
	carrier->SetImage(img);
	carrier->Read();
	if(extent == _T(".dcm"))
	{
		assert(img->GetFormatType() == Image::Format::Grey);

		m_img_rev = new Image(img->GetSize(),NOVA::Image::Pixel::UChar,NOVA::Image::Format::Grey,img->GetUnit());
		unsigned char* p_rev = (unsigned char*)m_img_rev->GetPixelPointer();
		short* p_img = (short*)img->GetPixelPointer();
		long int  size = img->GetSize().x()*(long int)img->GetSize().y();
		float width = 0;
		img->Get<float>("WindowWidth", width);
		float _center = 0;
		img->Get<float>("WindowCenter", _center);
		for(long int i = 0;i<size;i++,p_img++,p_rev++)
		{
			float tmp = (*p_img-_center+0.5*width)*255/width;
			if(tmp < 0)
				*p_rev = 0;
			else if(tmp > 255)
				*p_rev = 255;
			else *p_rev = tmp;
		}
		swap(img ,m_img_rev);
		//delete img_rev;
	}
	if(m_pImg)
	{delete m_pImg;m_pImg = 0L;}
	m_pImg = img;
	
	// to preview the implementation of gauss algorithm
	ImageProcessing::GaussianImageFilter *gauss = new ImageProcessing::GaussianImageFilter();
	string pre_test = gauss->GetImplementation();
	delete gauss;
	if("Linear_CPP" == pre_test)
		GetMenuBar()->Enable(ID_CUDA,true);
	GetMenuBar()->Enable(ID_LinearCPP,true);//for single thread;
	//GetMenuBar()->Enable(ID_OPENCL,true);
	//GetMenuBar()->Enable(ID_OPENGL,true);
	
		GetMenuBar()->Enable(ID_ShowSource,true);//for multi thread
	//((wxMenuItem*)(wxWindow::FindWindowById(ID_GAUSS,this)))->Enable(true);
	//((wxMenuItem*)this->FindWindow(ID_GAUSS))->Enable(true);
	}
	delete carrier;

	//cout<<img->GetWidth()<<endl;
	
	/*if (!p.empty()){



 		m_bmp = new wxBitmap(wxFileName(p).GetFullPath(),wxBITMAP_TYPE_BMP );
		int w = m_bmp->GetWidth();
		int h = m_bmp->GetHeight();

		

		wxImage img = m_bmp->ConvertToImage();
		m_pImg = new NOVA::Image(w,h,Pixel::Uint8,3,1.0,1.0,"CPU-Linear");

		unsigned char * pBuffer =(unsigned char *) m_pImg->GetDataPointer();

		for(int i=0;i<200;i++){
			for(int j=0;j<200;j++){
				pBuffer[(i + j*w)*3  ] = img.GetRed(i,j);
				pBuffer[(i + j*w)*3+1] = img.GetGreen(i,j);
				pBuffer[(i + j*w)*3+2] = img.GetBlue(i,j);

			}
		}*/
	    int w = img->GetWidth();
		int h =  img->GetHeight();
		this->SetSize(w+10,h+55);
		if(m_canvas)
			delete m_canvas;
		m_canvas = new ImageCanvas( this,w,h );
		//static ImageCanvas* mycanvas = new ImageCanvas(this,w,h);



	//	m_canvas->SetSize(w,h);
	//	m_canvas->SetImage(img);
		m_canvas->Refresh();
	}


		// img.SaveFile("c:\\sf.bmp",wxBITMAP_TYPE_BMP);

	}



void MainFrame::OnGAUSS(wxCommandEvent& event)
{
	int i = event.GetId();
	//ImageProcessing::GaussianImageFilter *GaussProcess= new ImageProcessing::GaussianImageFilter(1.5);
	//string implement =GetMenuBar()->GetHelpString(i);

	std::string implement = GetMenuBar()->GetLabel(i);
	NOVA::Image *out_image;


	if (m_img_rev)
		out_image = m_img_rev;
	else
		out_image = m_pImg;



	//GaussProcess->Run(out_image,3);
	wxMYPictureFrame *my_process_result = new wxMYPictureFrame(this,out_image,implement);
	my_process_result->Show();
}


void MainFrame::OnShowSource(wxCommandEvent& WXUNUSED(event))
{
	 SourceFrame *frame = new SourceFrame(_("First.htm"), wxDefaultPosition, wxSize(640, 480));

    frame->Show();
 
}





 SourceFrame::SourceFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
   : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size,wxDEFAULT_FRAME_STYLE, wxT("Source code"))
{
	
	CreateStatusBar(2);
	
	m_SourceWindow = new SourceWindow(this);
	m_SourceWindow->SetRelatedFrame(this, _("Source window : %s"));


	 m_SourceWindow->SetRelatedStatusBar(0);
	 wxStandardPaths p;
	 wxString path = p.GetExecutablePath();
	 OutputDebugString(path.c_str());
	 path.Replace("CMIPDemo.exe",title);
	// OutputDebugString(path.c_str());
	//m_SourceWindow->LoadFile(wxFileName(wxT("source-1.htm")));
	 m_SourceWindow->LoadFile(wxFileName(path));

	
}
void SourceFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{

    // true is to force the frame to close
    Close(true);
}


//void MainFrame::OnBack(wxCommandEvent& WXUNUSED(event))
//{
//    if (!m_Html->HistoryBack())
//    {
//        wxMessageBox(_("You reached prehistory era!"));
//    }
//}
//
//void MainFrame::OnForward(wxCommandEvent& WXUNUSED(event))
//{
//    if (!m_Html->HistoryForward())
//    {
//        wxMessageBox(_("No more items in history!"));
//    }
//}
//
//void MainFrame::OnProcessor(wxCommandEvent& WXUNUSED(event))
//{
//    m_Processor->Enable(!m_Processor->IsEnabled());
//    m_Html->LoadPage(m_Html->GetOpenedPage());
//}

//void MainFrame::PrepareDC(wxDC& dc)
//{
//    dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
//    dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
//    dc.SetUserScale( m_xUserScale, m_yUserScale );
//    dc.SetMapMode( m_mapMode );
//}
